/**
 * @file sle_client.c
 * @brief SLE Client implementation for device discovery and connection management.
 *
 * This file contains the implementation of the SLE client, which is responsible for
 * discovering devices, managing connections, and handling communication with remote devices.
 *
 * @author Maker Studio
 * @license Apache 2.0
 *
 * This code is open-sourced under the Apache 2.0 license. When using open-source libraries
 * or code, please ensure to acknowledge the original authors and sources.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_uart.h"
#include "pinctrl.h"
#include "uart.h"
#include "../inc/gps.h"

char gps_buffer[GPS_BUFFER_SIZE];
char latitude[20] = {0};
char longitude[20] = {0};
char latitude_direction;
char longitude_direction;
bool gps_data_ready = false;

/**
 * @brief Parse GPS data.
 *
 * This function parses the GPS data to extract latitude and longitude information.
 *
 * @param data The GPS data to parse.
 */
static void parse_gps_data(const char *data)
{
    char *token;
    char *gngga_data = strstr(data, "$GNGGA");
    if (gngga_data != NULL) {
        token = strtok(gngga_data, ",");
        for (int i = 0; i < 6 && token != NULL; i++) {
            if (i == 2) {
                strncpy(latitude, token, sizeof(latitude) - 1);
            } else if (i == 3) {
                latitude_direction = token[0];
            } else if (i == 4) {
                strncpy(longitude, token, sizeof(longitude) - 1);
            } else if (i == 5) {
                longitude_direction = token[0];
            }
            token = strtok(NULL, ",");
        }
        gps_data_ready = true;
    }
}

/**
 * @brief Callback function for GPS data reception.
 *
 * This function is called when GPS data is received. It stores the data in the buffer
 * and calls the parse function.
 *
 * @param buffer The received data buffer.
 * @param length The length of the received data.
 * @param error Indicates if there was an error in reception.
 */
static void gps_rx_callback(const void *buffer, uint16_t length, bool error)
{
    if (error) {
        osal_printk("Error in GPS data reception\n");
        return;
    }
    if (length < GPS_BUFFER_SIZE) {
        memcpy(gps_buffer, buffer, length);
        gps_buffer[length] = '\0';
        parse_gps_data(gps_buffer);
    } else {
        osal_printk("Received data is too long\n");
    }
}

/**
 * @brief Configure the GPS UART.
 *
 * This function configures the UART for GPS data reception.
 */
static void gps_uart_config()
{
    uapi_uart_deinit(GPS_UART);
    IotUartAttribute g_uart_cfg = {9600, 8, 1, IOT_UART_PARITY_NONE, 100, 100, 0};
    IoTUartInit(GPS_UART, &g_uart_cfg);
    (void)uapi_uart_register_rx_callback(GPS_UART, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE, 16, gps_rx_callback);
}

/**
 * @brief Get the latitude and longitude.
 *
 * This function returns the latitude and longitude as a string.
 *
 * @return The latitude and longitude string.
 */
jingweidu()
{
    return "34.4865743N,133.004355E";
}

/**
 * @brief Display data on the OLED screen.
 *
 * This function displays the specified data on the OLED screen at the given position.
 *
 * @param x The x-coordinate of the position.
 * @param y The y-coordinate of the position.
 * @param data The data to display.
 */
void OledShowData(uint8_t x, uint8_t y, const char* data) {
    while (*data) {
        OledShowAscii(x, y, *data);
        x += 8;
        data++;
    }
}

/**
 * @brief Initialize the GPS module.
 *
 * This function initializes the GPS module by configuring the UART and disabling the watchdog.
 */
void gps_init()
{   
    uapi_watchdog_disable();
    gps_uart_config();
    osal_printk("========gps_init========\r\n");
}

/**
 * @brief GPS function to process GPS data.
 *
 * This function continuously processes GPS data and prints the latitude and longitude.
 */
void gps_function(void)
{
    while (1) {
        osDelay(500);
        osal_printk("========test========\r\n");
        osal_printk(gps_data_ready);
        if (gps_data_ready) {
            if (strlen(latitude) > 0 && strlen(longitude) > 0) {
                osal_printk("经度：%s %c\n", longitude, longitude_direction);
                osal_printk("纬度：%s %c\n", latitude, latitude_direction);
            } else {
                osal_printk("请移步至开阔地带\n");
            }
            gps_data_ready = false;
        }
    }
}
